#include "linklist.h"

extern int errno;
//创建函数
db_list_pt db_list_create(void)
{
    db_list_pt list_head = NULL;
    list_head = (db_list_pt)malloc(sizeof(db_ldata_t));
    if (list_head == NULL)
    {
        errno = ENOMEM;
        return NULL;
    }
    list_head->limit_size = 0;
    list_head->head = (db_lnode_pt)malloc(sizeof(db_lnode_t));
    if (list_head->head == NULL)
    {
        errno = ENOMEM;
        return NULL;
    }

    //头节点首尾都是NULL
    list_head->head->next = list_head->head->prev = NULL;
    list_head->head->data = NULL;
    list_head->tail = list_head->head;
    return list_head;
}

//插入到第num个前面的位置
int __db_list_insert_before(db_list_t **list_head, int num, void *new_node_data)
{
    u32 counter = 1;
    db_lnode_pt current = NULL;
    db_lnode_pt new_node = NULL;

    if (list_head == NULL || *list_head == NULL)
    {
        errno = EINVAL;
        return -1;
    }
    //当size不为0时
    if ((*list_head)->limit_size != 0)
    {
        //申请地址空间
        new_node = (db_lnode_pt)malloc(sizeof(db_lnode_t));
        if (new_node == NULL)
        {
            errno = ENOMEM;
            return -1;
        }
        new_node->data = new_node_data;
        new_node->prev = new_node->next = NULL;
        //当num合法时
        if (num > 0 && num <= (*list_head)->limit_size)
        {
            //遍历得到第num个节点
            current = (*list_head)->head;
            while (counter < num)
            {
                counter++;
                current = current->next;
            }
            //如果要插入到第一个节点，此时current是第一个节点
            if (counter == 1)
            {
                //将current的prev指向新节点
                (*list_head)->head->prev = new_node;
                //新节点的下一个指向current
                new_node->next = (*list_head)->head;
                //将链表头指向新节点
                (*list_head)->head = new_node;
                (*list_head)->limit_size++;
                return 0;
            }
            //如果不是第一个节点
            current->prev->next = new_node;
            new_node->prev = current->prev;
            current->prev = new_node;
            new_node->next = current;
            (*list_head)->limit_size++;
            return 0;
        }
        else
        {
            errno = EINVAL;
            free(new_node);
            new_node = NULL;
            return -1;
        }
    }
    else
    {
        if (num != 0)
        {
            errno = EINVAL;
            return -1;
        }
        (*list_head)->head->data = new_node_data;
        (*list_head)->limit_size++;
        return 0;
    }
}

//插入到第num个后面的位置
int __db_list_insert_after(db_list_t **list_head, int num, void *new_node_data)
{
    u32 counter = 1;
    db_lnode_pt current = NULL;
    db_lnode_pt new_node = NULL;

    if (list_head == NULL || *list_head == NULL)
    {
        errno = EINVAL;
        return -1;
    }
    //当size不为0时
    if ((*list_head)->limit_size != 0)
    {
        //申请地址空间
        new_node = (db_lnode_pt)malloc(sizeof(db_lnode_t));
        if (new_node == NULL)
        {
            errno = ENOMEM;
            return -1;
        }
        new_node->data = new_node_data;
        new_node->prev = new_node->next = NULL;
        //当num合法时
        if (num > 0 && num <= (*list_head)->limit_size)
        {
            //遍历得到第num个节点
            current = (*list_head)->head;
            while (counter < num)
            {
                counter++;
                current = current->next;
            }
            //如果要插入到第一个节点的后一个，此时current是第一个节点
            if (counter == 1)
            {
                //将current的next指向新节点
                (*list_head)->head->next = new_node;
                (*list_head)->tail = new_node;
                //新节点的前一个指向current
                new_node->prev = (*list_head)->head;

                (*list_head)->limit_size++;
                return 0;
            }
            //如果不是第一个节点
            current->next->prev = new_node;
            new_node->next = current->next;
            current->next = new_node;
            new_node->prev = current;
            (*list_head)->limit_size++;
            return 0;
        }
        else
        {
            errno = EINVAL;
            free(new_node);
            new_node = NULL;
            return -1;
        }
    }
    else
    {
        if (num != 0)
        {
            errno = EINVAL;
            return -1;
        }
        (*list_head)->head->data = new_node_data;
        (*list_head)->limit_size++;
        return 0;
    }
}

//删除函数
void __db_list_delete(db_list_t **list_head, int num)
{
    int counter = 1;
    db_lnode_pt current = NULL;
    db_lnode_pt tmp = NULL;
    if (list_head == NULL || *list_head == NULL)
    {
        errno = EINVAL;
        return;
    }
    current = (*list_head)->head;
    while (counter < num)
    {
        counter++;
        current = current->next;
    }
    if (counter == 1)
    {
        tmp = current;
        (*list_head)->head = current->next;
        free(tmp);
        tmp = NULL;
        (*list_head)->head->prev = NULL;
        (*list_head)->limit_size--;
        return;
    }
    else
    {
        //如果删除的是最后一个节点
        if ((*list_head)->limit_size == counter)
        {
            tmp = (*list_head)->tail;
            (*list_head)->tail = tmp->prev;
            free(tmp);
            (*list_head)->tail->next = NULL;
            (*list_head)->limit_size--;
            return;
        }
        else
        {
            tmp = current;
            current->next->prev = current->prev;
            current->prev->next = current->next;
            free(tmp);
            tmp = NULL;
            (*list_head)->limit_size--;
            return;
        }
    }
}

//查找，第几个

void *__db_list_visit(db_list_t **list_head, int num)
{
    int counter;
    db_lnode_pt current = (*list_head)->head;
    if (list_head == NULL || *list_head == NULL || num > (*list_head)->limit_size)
    {
        errno = EINVAL;
        return NULL;
    }
    for (counter = 0; counter < num - 1; counter++)
    {
        current = current->next;
    }
    return current->data;
}

//遍历
void __db_list_travel(db_list_pt list_head, void (*do_function)(void *))
{
    u32 i = 0;
    if (list_head->limit_size < 0 || list_head == NULL)
    {
        errno = EINVAL;
        return;
    }
    db_lnode_pt p = list_head->head;
    for (i = 0; i < list_head->limit_size; i++)
    {
        (*do_function)(p->data);
        p = p->next;
    }
}
void __db_list_travel2(db_list_pt list_head)
{
    u32 i = 0;
    if (list_head->limit_size < 0 || list_head == NULL)
    {
        errno = EINVAL;
        return;
    }
    db_lnode_pt p = list_head->head;
    for (i = 0; i < list_head->limit_size; i++)
    {
        db_ldata_pt data = (db_ldata_pt)p->data;
        printf("id:%d,flag:%d,buffer:%s\n", data->id, data->flag, data->send_buffer);
        p = p->next;
    }
}

void __db_list_modify(db_list_t *list_head, int num, void *new_node_data)
{
    int counter = 0;
    db_lnode_pt current = NULL;
    if (list_head == NULL || num < 0 || num > list_head->limit_size)
    {
        errno = EINVAL;
        return;
    }
    current = list_head->head;
    while (counter != num - 1)
    {
        current = current->next;
        counter++;
    }
    current->data = new_node_data;
}
//寻找某个值
int __db_list_search(db_list_t **list_head, void *find_data, int (*compare)(void *, void *))
{
    int counter = 1;
    db_lnode_pt current = NULL;
    if ((*list_head) == NULL || list_head == NULL)
    {
        errno = EINVAL;
        return -1;
    }
    current = (*list_head)->head;
    while (compare(current->data, find_data) != 0 && current->next != NULL)
    {
        current = current->next;
        counter++;
    }
    if (current->next == NULL && compare(current->data, find_data) != 0)
    {
        return 0;
    }
    return counter;
}
